#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
数据库模块
"""

import os
import logging
from pathlib import Path
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session

# 创建基类
Base = declarative_base()


class Database:
    """数据库管理类"""
    
    def __init__(self, config):
        """初始化数据库连接
        
        Args:
            config: 数据库配置信息
        """
        self.config = config
        self.engine = None
        self.session_factory = None
        self._setup_engine()
    
    def _setup_engine(self):
        """设置数据库引擎"""
        db_config = self.config.get("database", {})
        db_type = db_config.get("type", "sqlite")
        
        if db_type == "sqlite":
            db_path = db_config.get("path", "./data/scheduler.db")
            # 确保目录存在
            os.makedirs(os.path.dirname(db_path), exist_ok=True)
            # 创建引擎
            self.engine = create_engine(f"sqlite:///{db_path}", echo=False)
        else:
            # 其他数据库类型的支持可以在这里添加
            raise ValueError(f"不支持的数据库类型: {db_type}")
        
        # 创建会话工厂
        self.session_factory = scoped_session(sessionmaker(bind=self.engine))
        
        logging.info(f"数据库引擎已初始化: {db_type}")
    
    def create_tables(self):
        """创建所有表"""
        Base.metadata.create_all(self.engine)
        logging.info("数据库表已创建")
    
    def get_session(self):
        """获取数据库会话
        
        Returns:
            Session: 数据库会话
        """
        return self.session_factory()
    
    def close(self):
        """关闭数据库连接"""
        if self.session_factory:
            self.session_factory.remove()
        if self.engine:
            self.engine.dispose()
        logging.info("数据库连接已关闭")

    def get_scripts(self):
        """获取所有脚本列表

        Returns:
            list: 脚本对象列表
        """
        from .models import Script
        session = self.get_session()
        try:
            scripts = session.query(Script).all()
            return scripts
        finally:
            session.close()
            
    def get_script_names(self):
        """获取所有脚本名称列表

        Returns:
            list: 脚本名称列表
        """
        from .models import Script
        session = self.get_session()
        try:
            scripts = session.query(Script).all()
            return [script.name for script in scripts]
        finally:
            session.close()

    def get_script_by_id(self, script_id):
        """根据ID获取脚本
        
        Args:
            script_id: 脚本ID
            
        Returns:
            Script: 脚本对象
        """
        from .models import Script
        session = self.get_session()
        try:
            return session.query(Script).filter(Script.id == script_id).first()
        finally:
            session.close()

    def get_script_by_name(self, script_name):
        """根据名称获取脚本
        
        Args:
            script_name: 脚本名称
            
        Returns:
            Script: 脚本对象
        """
        from .models import Script
        session = self.get_session()
        try:
            return session.query(Script).filter(Script.name == script_name).first()
        finally:
            session.close()
            
    def create_script(self, script_data):
        """创建新脚本
        
        Args:
            script_data: 脚本数据字典
            
        Returns:
            Script: 创建的脚本对象
        """
        import uuid
        from .models import Script
        
        session = self.get_session()
        try:
            # 检查脚本名称是否已存在
            existing = session.query(Script).filter(Script.name == script_data['name']).first()
            if existing:
                raise ValueError(f"脚本名称已存在: {script_data['name']}")
                
            # 创建新脚本
            script = Script(
                id=str(uuid.uuid4()),
                name=script_data['name'],
                description=script_data.get('description', ''),
                content=script_data.get('content', ''),
                script_type=script_data.get('script_type', 'Python')
            )
            
            session.add(script)
            session.commit()
            
            return script
        except Exception as e:
            session.rollback()
            logging.error(f"创建脚本失败: {str(e)}")
            raise e
        finally:
            session.close()
    
    def update_script(self, script_id, script_data):
        """更新脚本
        
        Args:
            script_id: 脚本ID
            script_data: 脚本数据字典
            
        Returns:
            Script: 更新后的脚本对象
        """
        from .models import Script
        
        session = self.get_session()
        try:
            # 获取脚本
            script = session.query(Script).filter(Script.id == script_id).first()
            if not script:
                raise ValueError(f"脚本不存在: {script_id}")
            
            # 如果要更新名称，检查名称是否已存在
            if 'name' in script_data and script_data['name'] != script.name:
                existing = session.query(Script).filter(Script.name == script_data['name']).first()
                if existing:
                    raise ValueError(f"脚本名称已存在: {script_data['name']}")
                script.name = script_data['name']
            
            # 更新其他字段
            if 'description' in script_data:
                script.description = script_data['description']
            
            if 'content' in script_data:
                script.content = script_data['content']
            
            if 'script_type' in script_data:
                script.script_type = script_data['script_type']
            
            # 更新时间
            script.updated_at = datetime.datetime.now()
            
            session.commit()
            return script
        except Exception as e:
            session.rollback()
            logging.error(f"更新脚本失败: {str(e)}")
            raise e
        finally:
            session.close()
    
    def delete_script(self, script_id):
        """删除脚本
        
        Args:
            script_id: 脚本ID
            
        Returns:
            bool: 是否删除成功
        """
        from .models import Script
        
        session = self.get_session()
        try:
            # 获取脚本
            script = session.query(Script).filter(Script.id == script_id).first()
            if not script:
                raise ValueError(f"脚本不存在: {script_id}")
            
            # 删除脚本
            session.delete(script)
            session.commit()
            return True
        except Exception as e:
            session.rollback()
            logging.error(f"删除脚本失败: {str(e)}")
            return False
        finally:
            session.close()
            
    def get_tasks(self, status=None, limit=100):
        """获取任务列表
        
        Args:
            status: 任务状态过滤
            limit: 返回结果数量限制
            
        Returns:
            List[Task]: 任务对象列表
        """
        from .models import Task
        
        session = self.get_session()
        try:
            query = session.query(Task)
            if status:
                query = query.filter(Task.status == status)
            
            query = query.order_by(Task.created_at.desc()).limit(limit)
            return query.all()
        finally:
            session.close()
    
    def get_task_by_id(self, task_id):
        """根据ID获取任务
        
        Args:
            task_id: 任务ID
            
        Returns:
            Task: 任务对象
        """
        from .models import Task
        
        session = self.get_session()
        try:
            return session.query(Task).filter(Task.id == task_id).first()
        finally:
            session.close()